package com.ght.springboot.dao;

import net.sf.json.JSONObject;
import com.ght.springboot.api.query.CommentQuery;
import com.ght.springboot.api.query.ElasticSearchQuery;
import com.ght.springboot.elasticsearch.BaseOperates;
import com.ght.springboot.elasticsearch.Document;
import com.ght.springboot.elasticsearch.DocumentDB;
import com.ght.springboot.elasticsearch.ElasticsearchDsCfg;
import com.ght.springboot.vo.CommentBookVo;
import com.ght.springboot.vo.Criteria;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.*;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: haitao.gao
 * @create: 2019-01-29 09:35
 **/
public class IDDocumentDaoImpl implements IDDocumentDao{

    private JestClient client;


    private IDDocumentDaoImpl(JestClient client) {
        this.client = client;
    }

    /**
     * 插入
     *
     * @param doc 文档
     * @return 是佛插入成功
     */
    @Override
    public boolean insert(Document doc) {
        try {
            DocumentResult result = client.execute(new Index.Builder(doc)
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .refresh(true)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("insert exception", e);
        }
    }

    /**
     * 替换
     *
     * @param doc 文档
     * @return 是否执行成功
     */
    @Override
    public boolean replace(Document doc) {
        return update(doc);
    }

    /**
     * 更新
     *
     * @param doc 文档
     * @return 是否更新成功
     */
    @Override
    public boolean update(Document doc) {
        try {
            DocumentResult result = client.execute(new Update.Builder(doc)
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .refresh(true)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("update exception", e);
        }
    }

    /**
     * 删除
     *
     * @param id 文档id
     * @return 是否执行成功
     */
    @Override
    public boolean delete(long id) {
        try {
            DocumentResult result = client.execute(new Delete.Builder(String.valueOf(id))
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("delete exception", e);
        }
    }

    /**
     * 根据ID查询
     *
     * @param id id
     * @return 文档
     */
    @Override
    public Document searchById(long id) {
        try {
            DocumentResult result = client.execute(new Get.Builder(DocumentDB.INDICES, String.valueOf(id))
                    .type(DocumentDB.TYPE)
                    .build());
            return result.getSourceAsObject(Document.class);
        } catch (Exception e) {
            throw new RuntimeException("searchById exception", e);
        }
    }

    /**
     * 条件查询
     *
     * @param criterias 条件列表
     * @return 结果集
     */
    @Override
    public List<CommentBookVo> search(CommentQuery query) {
        try {

            List<CommentBookVo> result = new ArrayList<>();
            BaseOperates<CommentBookVo> baseOperates = new BaseOperates<>();
            ElasticSearchQuery<CommentQuery> query1 = new ElasticSearchQuery();
            query1.setMust(query);
            List<SearchResult.Hit<JSONObject, Void>> hitList = baseOperates.search(query1);
            hitList.forEach(hit->{
                Map<String,String> source = hit.source;
                CommentBookVo blackAddressVo = new CommentBookVo(source);
                result.add(blackAddressVo);
            });
            return result;
        } catch (Exception e) {
            throw new RuntimeException("search exception", e);
        }
    }

    private SearchSourceBuilder buildSearch(List<Criteria> criterias) {
        //指定查询的库表
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        if (criterias != null && !criterias.isEmpty()) {
            //构建查询条件必须嵌入filter中！
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            for (Criteria c : criterias) {
                boolQueryBuilder.filter(QueryBuilders.termQuery(c.getFieldName(), c.getFieldValue()));
            }

            searchSourceBuilder.query(boolQueryBuilder);
        }
        return searchSourceBuilder;
    }
    /**
     * 条件删除 ，ElasticSearch V5.1 以上可用
     *
     * @param criterias 条件
     * @return 删除的document数量
     */
    @Override
    public int deleteByQuery(List<Criteria> criterias) {
        try {
            JestResult result = client.execute(new DeleteByQuery.Builder(buildSearch(criterias).toString())
                    .addIndex(DocumentDB.INDICES)
                    .addType(DocumentDB.TYPE)
                    .build());

            return result.getJsonObject().get("deleted").getAsInt();
        } catch (Exception e) {
            throw new RuntimeException("deleteByQuery exception", e);
        }
    }

}
